package com.lxlg.lxlg_order.service.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lxlg.Lxlg_goods.client.GoodClient;
import com.lxlg.Lxlg_goods.client.param.MinusGoodNumberForm;
import com.lxlg.Lxlg_goods.client.result.FindGoodBySkuInfo;
import com.lxlg.core.utils.Result;
import com.lxlg.lxlg_massage.client.MassageClient;
import com.lxlg.lxlg_massage.client.param.SendMassageParam;
import com.lxlg.lxlg_order.alipay.config.AlipayConfig;
import com.lxlg.lxlg_order.client.param.*;
import com.lxlg.lxlg_order.common.OrderException.OrderException;
import com.lxlg.lxlg_order.common.OrderException.OrderExceptionCode;
import com.lxlg.lxlg_order.common.WebUtils;
import com.lxlg.lxlg_order.common.constvalue.AllOrderConstValue;
import com.lxlg.lxlg_order.common.constvalue.LogistsConstValue;
import com.lxlg.lxlg_order.common.constvalue.RechargeConstValue;
import com.lxlg.lxlg_order.common.redisconfig.ObjectRedisTemplate;
import com.lxlg.lxlg_order.common.util.TokenUtil;
import com.lxlg.lxlg_order.infra.mapper.GoodsOrderMapper;
import com.lxlg.lxlg_order.infra.mapper.OrderAndGoodsMapper;
import com.lxlg.lxlg_order.infra.mapper.OrderLogisticsMapper;
import com.lxlg.lxlg_order.infra.model.GoodsOrder;
import com.lxlg.lxlg_order.infra.model.OrderAndGoods;
import com.lxlg.lxlg_order.infra.model.OrderLogistics;
import com.lxlg.lxlg_order.service.service.GoodsOrderService;
import com.lxlg.lxlg_order.service.service.OrderAndGoodsService;
import com.lxlg.user_server.client.UserClient;
import com.lxlg.user_server.client.param.UserIntegralChangeForm;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author kevin
 * @since 2022-04-28
 */
@Service
public class GoodsOrderServiceImpl extends ServiceImpl<GoodsOrderMapper, GoodsOrder> implements GoodsOrderService {
    @Resource
    private RedissonClient rc;
    @Resource
    private RocketMQTemplate rocketMQTemplate;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private OrderAndGoodsMapper orderAndGoodsMapper;
    @Resource
    private OrderAndGoodsService orderAndGoodsService;
    @Resource
    private OrderLogisticsMapper orderLogisticsMapper;
    @Resource
    private UserClient userClient;
    @Resource
    private MassageClient massageClient;
    @Resource
    private ObjectRedisTemplate objectRedisTemplate;
//    private ObjectRedis
    @Resource
    private GoodClient goodClient;
    /**
     * 通过订单编号查看订单表
     * @param ordercode
     * @return
     */
    public GoodsOrder checkGoodsOrder(String ordercode){
        QueryWrapper<GoodsOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_code",ordercode);
        GoodsOrder one = getOne(queryWrapper);
        if(null==one){
            throw new OrderException(OrderExceptionCode.NOTEXSIT_ORDER_ERROR);
        }
        return one;
    }

    @Override
    public Result<String> addFormOrder(FormOrderForm formOrderForm) {
        //上锁查询锁定商品
        List<ByGoodsInfo> byGoodsInfos = formOrderForm.getByGoodsInfos();
        Double sumScore =0.0;
        BigDecimal sumPrice= new BigDecimal(0);
        BigDecimal reducePrice= new BigDecimal(0);
        RLock[] collect =new RLock[byGoodsInfos.size()];
        Integer i =0;
        for (ByGoodsInfo byGoodsInfo : byGoodsInfos) {
            sumScore+=byGoodsInfo.getConsumeOneScore();
            sumPrice=sumPrice.add(new BigDecimal(byGoodsInfo.getGoodsPayAllprice()));
            reducePrice=reducePrice.add(new BigDecimal(byGoodsInfo.getMerchantPriceOneResuce()));
//            collect[i]=rc.getLock(byGoodsInfo.getSkuId().toString());
            i++;
        }
//        RLock multiLock = rc.getMultiLock(collect);
//        multiLock.lock();
        //查询商品的库存判断库存是否足够
        for (ByGoodsInfo byGoodsInfo : byGoodsInfos) {
            Integer num=(Integer)objectRedisTemplate.opsForValue().get("number:"+byGoodsInfo.getSkuId());

            if(null==num){
                throw new OrderException(OrderExceptionCode.ORDER_NOGOODS_ERROR);
            }
            if(num<byGoodsInfo.getGoodsNum()){
                throw new OrderException(OrderExceptionCode.NOENOUGH_GOODS_ERROR);
            }
        }
        //判断积分是否够用
        Result<Double> doubleResult = userClient.inqueryUserIntegral();
        System.out.println(doubleResult.getMessage());
        System.out.println(doubleResult.getCode());
        System.out.println(doubleResult.getData());
        if(null==doubleResult.getData()){
            throw new OrderException(OrderExceptionCode.ORDER_NOGOODS_ERROR);
        }
        if(doubleResult.getData()<sumScore){
            throw new OrderException(OrderExceptionCode.SCORE_NOTENOUGH_ERROR);
        }
        //库存减少
        for (ByGoodsInfo byGoodsInfo : byGoodsInfos) {
            objectRedisTemplate.opsForValue().decrement("number:" + byGoodsInfo.getSkuId(),byGoodsInfo.getGoodsNum());
            MinusGoodNumberForm minusGoodNumberForm = new MinusGoodNumberForm();
            minusGoodNumberForm.setNum(byGoodsInfo.getGoodsNum());
            minusGoodNumberForm.setSkuid(byGoodsInfo.getSkuId());
//            minusGoodNumberForm.setValues();
            try {
                goodClient.minusGoodNumber(minusGoodNumberForm);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                System.out.println("可能执行库存减少");
            }
        }


        //生成订单
        GoodsOrder goodsOrder = new GoodsOrder();
        goodsOrder.setConsumeAllScore(sumScore);
        goodsOrder.setCreateTime(new Date());
        goodsOrder.setMerchantPriceResuce(reducePrice.toString());
        goodsOrder.setGoodsTotalPrice(sumPrice.toString());
        goodsOrder.setOrderCode("n"+UUID.randomUUID().toString()+new Date().toString().replace("-","").replace(" " ,""));
        goodsOrder.setOrderState(RechargeConstValue.Oreder_State_New);
        goodsOrder.setUserId(TokenUtil.getUserId());
        goodsOrder.setUserName(TokenUtil.getUserName());
        goodsOrder.setUserPhone(TokenUtil.getUserPhone());
        int insert = baseMapper.insert(goodsOrder);

        //循环商品生成中间表记录商品
        List<OrderAndGoods> oag= new ArrayList<>();
        for (ByGoodsInfo byGoodsInfo : byGoodsInfos) {
            Result<FindGoodBySkuInfo> goodBySku = goodClient.findGoodBySku(byGoodsInfo.getSkuId());
            FindGoodBySkuInfo data = goodBySku.getData();
            if(goodBySku.getCode()!=200){
                throw new OrderException(500,goodBySku.getMessage());
            }
            System.out.println("===========goodclient====");
            System.out.println(goodBySku.getCode());
            System.out.println(goodBySku.getMessage());
            System.out.println(goodBySku.getData());


            OrderAndGoods orderAndGoods = new OrderAndGoods();
            orderAndGoods.setGoodsName(data.getGoodsName());
            orderAndGoods.setGoodsNum(byGoodsInfo.getGoodsNum());
            orderAndGoods.setGoodsOrangePrice(data.getPrice());
            orderAndGoods.setGoodsPayAllprice(byGoodsInfo.getGoodsPayAllprice());
            orderAndGoods.setSkuId(byGoodsInfo.getSkuId());
            System.out.println(goodsOrder.getOrderId());
            orderAndGoods.setOrderId(goodsOrder.getOrderId());
            orderAndGoods.setMerchantId(byGoodsInfo.getSkuId());
            orderAndGoods.setMerchantName(data.getMerchantName());
            orderAndGoods.setMerchantPriceResuce(byGoodsInfo.getMerchantPriceOneResuce());
            oag.add(orderAndGoods);
        }


        boolean b = orderAndGoodsService.saveBatch(oag);


        //解锁
//        multiLock.unlock();

        //30分钟取消订单
        Message<String> message = MessageBuilder.withPayload(goodsOrder.getOrderCode()).build();
        rocketMQTemplate.asyncSend("formOrder_cancle", message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("发送取消订单成功");
            }

            @Override
            public void onException(Throwable e) {
                e.printStackTrace();
                System.out.println("发送取消订单失败");
            }
        },RechargeConstValue.FormOrder_Cancle_delayTimeLevel);

        return Result.getInstance(String.class).setData(goodsOrder.getOrderCode());

    }

    @Override
    public void payFormOrder(FormOrderPayFOrm formOrderPayFOrm, HttpServletResponse resp) throws IOException {
//        HttpServletRequest request = WebUtils.getRequest();

        GoodsOrder one = checkGoodsOrder(formOrderPayFOrm.getFormOrderCode());
        if(one==null){
            throw new OrderException(OrderExceptionCode.NOTEXSIT_ORDER_ERROR);
        }

        //================================================支付=======================================================================
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);


        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = one.getOrderCode();
        //付款金额，必填
        String total_amount = one.getGoodsTotalPrice();
        //订单名称，必填
        String subject =one.getUserName()+"的商品订单";

        //商品描述，可空
        String body ="商品购买";

        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
//                + "\"order_type\":\""+ AllOrderConstValue.order_type_form +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"body\":\""+ body +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //若想给BizContent增加其他可选请求参数，以增加自定义超时时间参数timeout_express来举例说明
        //alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
        //		+ "\"total_amount\":\""+ total_amount +"\","
        //		+ "\"subject\":\""+ subject +"\","
        //		+ "\"body\":\""+ body +"\","
        //		+ "\"timeout_express\":\"10m\","
        //		+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节

        //发送延时消息查看是否回调 ，redis中存储订单号设置状态为0表示没有支付回调
        OrderPayBackParam orderPayBackParam = new OrderPayBackParam();
        orderPayBackParam.setOrderCode(out_trade_no);
        orderPayBackParam.setOrderType(AllOrderConstValue.order_type_form);
        Message<OrderPayBackParam> message = MessageBuilder
                .withPayload(orderPayBackParam)//消息参数
//                .setHeader()//消息头
                .build();
        rocketMQTemplate.syncSend("Check_Order_pay",message,3000, RechargeConstValue.recharge_pay_delayTimeLevel);

        String result2=null;
        try {
            result2 = alipayClient.pageExecute(alipayRequest).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        redisTemplate.opsForValue().set("order_pay:"+out_trade_no+"order_type"+AllOrderConstValue.order_type_form,"0",31, TimeUnit.MINUTES);
        //输出
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().write(result2);

    }
    //支付回调
    @Override
    public void formorderPayBack(String orderCode) {
        //查询改订单
        GoodsOrder one = checkGoodsOrder(orderCode);

        //删除redis中的订单
        redisTemplate.delete("order_pay:"+orderCode+"order_type"+AllOrderConstValue.order_type_form);

        //修改订单状态  已经支付
        System.out.println("开始修改订单状态");
        one.setOrderState(AllOrderConstValue.order_payState_pay);
        saveOrUpdate(one);
        QueryWrapper<OrderAndGoods> queryWrapper = new QueryWrapper<>();
        //修改订单关联商品的状态
        QueryWrapper<OrderAndGoods> order_id = queryWrapper.eq("order_id", one.getOrderId());
        List<OrderAndGoods> goods = orderAndGoodsService.getBaseMapper().selectList(queryWrapper);
        for (OrderAndGoods good : goods) {
            good.setGoodsState(AllOrderConstValue.order_goodsState_pay);
        }
        orderAndGoodsService.saveBatch(goods);
        //用户减少积分


        UserIntegralChangeForm userIntegralChangeForm = new UserIntegralChangeForm();
        userIntegralChangeForm.setIntegralRecord(one.getConsumeAllScore());
        userIntegralChangeForm.setIntegralUpdateLog("积分减少");
        userClient.changeIntegralDeduction(userIntegralChangeForm);

        //多个用户增加积分
        UserIntegralChangeForm userIntegralChangeForm1 = new UserIntegralChangeForm();
        userIntegralChangeForm1.setIntegralRecord(Double.parseDouble(one.getGoodsTotalPrice()));
        userIntegralChangeForm1.setIntegralUpdateLog("积分增加");
        userClient.changeUserIntegral(userIntegralChangeForm1);


        //获取订单中的商品  提醒商家发货

        List<OrderAndGoods> goodsList = orderAndGoodsMapper.getListOrderAndGoods(one.getOrderId());
        for (OrderAndGoods orderAndGoods : goodsList) {
            Integer skuId = orderAndGoods.getSkuId();
            //修改订单关联商品的状态
            orderAndGoods.setGoodsState(AllOrderConstValue.order_goodsState_pay);
            //查询商品商家
            Result<FindGoodBySkuInfo> goodBySku = goodClient.findGoodBySku(skuId);
            FindGoodBySkuInfo data = goodBySku.getData();
            String merchantName = data.getMerchantName();
            SendMassageParam sendMassageParam = new SendMassageParam();
            sendMassageParam.setMsgAcceptName(merchantName);
            sendMassageParam.setMsgSendName(TokenUtil.getUserName());
            sendMassageParam.setMsgTypeId(2);
            sendMassageParam.setMsgContent("商品编号为："+orderAndGoods.getSkuId()+"的"+data.getGoodsName()+"商品需要发送"+orderAndGoods.getGoodsNum()+"件商品");
//            massageClient.Sendmessage(sendMassageParam);

        }
        //保存订单关联的商品状态
        orderAndGoodsMapper.setlistState(goodsList);




    }
    //取消订单
    @Override
    public Result<String> cancleFormOrder(String ordernu) {
        //查询订单
        GoodsOrder goodsOrder = checkGoodsOrder(ordernu);

        //查询订单状态
        if (goodsOrder.getOrderState()!= AllOrderConstValue.order_payState_nopay) {
            throw new OrderException(OrderExceptionCode.ORDER_CANTCANCLE_EXCEPION);
        }
        //查询订单的商品
        List<OrderAndGoods> listOrderAndGoods = orderAndGoodsMapper.getListOrderAndGoods(goodsOrder.getOrderId());
        for (OrderAndGoods listOrderAndGood : listOrderAndGoods) {
            //修改OrderAndGoods状态
            listOrderAndGood.setGoodsState(AllOrderConstValue.order_goodsState_cancle);
            //修改商品库存
            redisTemplate.opsForValue().increment("number:" + listOrderAndGood.getSkuId(),listOrderAndGood.getGoodsNum());
            orderAndGoodsMapper.insert(listOrderAndGood);
        }
        //修改订单状态
        goodsOrder.setOrderState(AllOrderConstValue.order_payState_cancle);
        return Result.getInstance(String.class).setData("取消订单成功");
    }

    @Override
    public Result<String> doDeliverGoods(DeliverGoodsForm deliverGoodsForm) {
        GoodsOrder goodsOrder = checkGoodsOrder(deliverGoodsForm.getOrdercode());
//        OrderLogistics orderLogistics = new OrderLogistics().b;
        OrderLogistics orderlogistc = OrderLogistics.builder().build().setDeliveryman(deliverGoodsForm.getDeliveryman())
                .setDeliverymanPhone(deliverGoodsForm.getDeliverymanPhone())
                .setLogisticsCode(deliverGoodsForm.getLogisticsCode())//投递单号
                .setLogisticsContent("XXX商品")//描述
                .setLogisticsCompanyCode(deliverGoodsForm.getLogisticsCompanyCode())//公司
                .setSkuId(deliverGoodsForm.getSkuId())//商品id
                .setOrderCode(deliverGoodsForm.getOrdercode());//点单编号
        int insert = orderLogisticsMapper.insert(orderlogistc);
        if(insert<1){
            throw new OrderException(OrderExceptionCode.NOTEXSIT_GOODS_ERROR);
        }
        return Result.getInstance(String.class).setData("物品投递成功");
    }

    /**
     * 修改物流状态
     * @param logisticsStateForm
     *
     * @return
     */
    @Override
    public Result<String> doChangedeliverGoodsState(LogisticsStateForm logisticsStateForm) {
        QueryWrapper<OrderLogistics> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("logistics_code",logisticsStateForm.getLogisticsCode());
        OrderLogistics orderLogistics = orderLogisticsMapper.selectOne(queryWrapper);
        orderLogistics.setLogisticsState(logisticsStateForm.getLogisticsState());
        if(logisticsStateForm.getLogisticsState()== LogistsConstValue.logists_state_wate_pick){
            orderLogistics.setTakeCode(RandomUtil.randomNumbers(6));
        }
        if(logisticsStateForm.getLogisticsState()== LogistsConstValue.logists_state_recive){
            orderLogistics.setTakeCode("");
        }

        orderLogisticsMapper.updateById(orderLogistics);
        return Result.getInstance(String.class).setData("修改物流信息成功");
    }


}
